package com.example.niu.qqapp

import android.animation.Animator
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ImageSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.viewpager.widget.PagerAdapter
import com.example.niu.qqapp.adapter.ContactsPageListAdapter
import com.example.niu.qqapp.adapter.MessagePageListAdapter
import com.example.niu.qqapp.databinding.FragmentMainBinding
import com.google.android.material.snackbar.Snackbar
import com.niuedu.ListTree
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit


// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

class MainFragment : Fragment() {

    companion object {
        //创建集合（一棵树）
        private val tree = ListTree()

        fun getContacts(): ListTree {
            return tree
        }
    }

    private var _binding: FragmentMainBinding? = null
    private val binding get() = _binding!!

    private lateinit var groupNode1: ListTree.TreeNode
    private lateinit var groupNode2: ListTree.TreeNode
    private lateinit var groupNode3: ListTree.TreeNode
    private lateinit var groupNode4: ListTree.TreeNode
    private lateinit var groupNode5: ListTree.TreeNode

    //创建一个数组，有三个元素，三个元素都初始化为空
    private val listViews = arrayOfNulls<ViewGroup?>(3)

    //联系人Adpater，为了更新数据而设
    private var contactsAdapter: ContactsPageListAdapter? = null

    //用于停止订阅的东西
    private var observableDisposable: Disposable? = null

    private var fragmentListener: FragmentListener? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //创建三个RecyclerView，分别对应QQ消息页，QQ联系人页，QQ空间页
        val v1 = RecyclerView(context!!)
        val v2 = createContactsPage()
        val v3 = RecyclerView(context!!);
        listViews[0] = v1
        listViews[1] = v2 as ViewGroup
        listViews[2] = v3

        //为RecyclerView们设置适配器与LayoutManager
        //消息页面
        (listViews[0] as RecyclerView).let {
            it.adapter = MessagePageListAdapter()
            it.layoutManager = LinearLayoutManager(context)
        }
        //QQ空间页面
//        (listViews[2] as RecyclerView).let{
//            it.adapter =
//            it.layoutManager = LinearLayoutManager(context)
//        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        _binding = FragmentMainBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        //将Adapter设置给ViewPager实例
        binding.viewPager.adapter = ViewPageAdapter()
        binding.tabLayout.setupWithViewPager(binding.viewPager);

        //响应左上角的图标点击事件，显示抽屉页面
        binding.headImage.setOnClickListener {
            //创建抽屉页面
            val drawerLayout = activity!!.layoutInflater.inflate(
                R.layout.drawer_layout, view as ViewGroup, false
            )

            //先计算一下消息页面中，左边一排图像的大小，在界面构建器中设置的是dp
            //在代码中只能用像素，所以这里要换算一下，因为不同的屏幕分辩率，dp对应
            //的像素数是不同的
            val messageImageWidth = dip2px(activity!!, 60.0f)
            //计算抽屉页面的宽度，view是FrameLayout，
            //利用getWidth()即可获得它当前的宽度
            val drawerWidth = view.width - messageImageWidth
            //设置抽屉页面的宽度
            drawerLayout.layoutParams.width = drawerWidth
            //将抽屉页面加入FrameLayout中
            view.addView(drawerLayout)

            //动画持续的时间
            val duration = 500L;

            //创建一个动画，让抽屉页面向右移，注意它是从左移出来的，
            //所以其初始位值设置为-drawerWidth/2，即有一半位于屏幕之外。
            val animatorDrawer = ObjectAnimator.ofFloat(
                drawerLayout,
                "translationX", -drawerWidth / 2f, 0f
            )

            //把原内容的根控件搞到最上层，这样在移动时能一直看到它（QQ就是这个效果）
            binding.contentLayout.bringToFront();
            //创建动画，移动原内容，从0位置移动抽屉页面宽度的距离（注意其宽度不变）
            val animatorContent = ObjectAnimator.ofFloat(
                binding.contentLayout,
                "translationX", 0f, drawerWidth.toFloat()
            )

            //创建蒙板View
            val maskViewDrawer = View(context)
            maskViewDrawer.setBackgroundColor(Color.GRAY)
            //必须将其初始透明度设为完全透明
            maskViewDrawer.alpha = 0f
            //添加到FragmentLayout中
            view.addView(maskViewDrawer)
            //将蒙板View搞到最最上层
            maskViewDrawer.bringToFront()
            //当点击蒙板View时，隐藏抽屉页面
            maskViewDrawer.setOnClickListener {
                //动画反着来，让抽屉消失
                //创建动画，移动原内容，从0位置移动抽屉页面宽度的距离（注意其宽度不变）
                val animatorContent = ObjectAnimator.ofFloat(
                    binding.contentLayout,
                    "translationX", drawerWidth.toFloat(), 0f
                )
                //移动蒙板的动画
                val animatorMask = ObjectAnimator.ofFloat(
                    maskViewDrawer,
                    "translationX", drawerWidth.toFloat(), 0f
                )
                //创建蒙板逐渐变亮的动画
                val animatorMaskAlpha = ObjectAnimator.ofFloat(maskViewDrawer, "alpha", 0.6f, 0f);
                //创建动画，让抽屉页面向右移，注意它是从左移出来的，
                //所以其初始位值设置为-drawerWidth/2，即有一半位于屏幕之外。
                val animatorDrawer = ObjectAnimator.ofFloat(
                    drawerLayout,
                    "translationX", 0f, -drawerWidth / 2f
                )

                //创建动画集合，同时播放4个动画
                val animatorSet = AnimatorSet()
                animatorSet.playTogether(animatorContent, animatorMask, animatorMaskAlpha, animatorDrawer)
                animatorSet.duration = duration
                //设置侦听器，主要侦听动画关闭事件
                animatorSet.addListener(object : Animator.AnimatorListener {
                    override fun onAnimationRepeat(p0: Animator?) {}
                    override fun onAnimationEnd(p0: Animator?) {
                        //动画结束，将蒙板和抽屉页面删除
                        view.removeView(maskViewDrawer);
                        view.removeView(drawerLayout);
                    }

                    override fun onAnimationCancel(p0: Animator?) {}
                    override fun onAnimationStart(p0: Animator?) {}
                })
                animatorSet.start();
            }

            //创建移动蒙板的动画
            val animatorMask = ObjectAnimator.ofFloat(
                maskViewDrawer,
                "translationX", 0f, drawerWidth.toFloat()
            );
            //创建蒙板逐渐变暗的动画
            val animatorMaskAlpha = ObjectAnimator.ofFloat(maskViewDrawer, "alpha", 0f, 0.6f);

            //创建动画集合，同时播放三个动画
            val animatorSet = AnimatorSet()
            animatorSet.playTogether(animatorContent, animatorMask, animatorMaskAlpha, animatorDrawer);
            animatorSet.duration = duration
            animatorSet.start()
        }

        //将消息TabItem置为选中状态
        //        tabLayout.getTabAt(0)?.setIcon(R.drawable.message_focus)it
        //        tabLayout.getTabAt(1)?.setIcon(R.drawable.contacts_normal)
        //        tabLayout.getTabAt(2)?.setIcon(R.drawable.space_normal)
        //        tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
        //            override fun onTabSelected(tab: TabLayout.Tab) {
        //                when {
        //                    tab.position === 0 -> tab.setIcon(R.drawable.contacts_focus)
        //                    tab.position === 1 -> tab.setIcon(R.drawable.message_focus)
        //                    else -> tab.setIcon(R.drawable.spacs_focus)
        //                }
        //            }
        //            override fun onTabUnselected(tab: TabLayout.Tab) {
        //                when {
        //                    tab.position === 0 -> tab.setIcon(R.drawable.contacts_normal)
        //                    tab.position === 1 -> tab.setIcon(R.drawable.message_normal)
        //                    else -> tab.setIcon(R.drawable.space_normal)
        //                }
        //            }
        //            override fun onTabReselected(tab: TabLayout.Tab) {
        //                when {
        //                    tab.position === 0 -> tab.setIcon(R.drawable.contacts_focus)
        //                    tab.position === 1 -> tab.setIcon(R.drawable.message_focus)
        //                    else -> tab.setIcon(R.drawable.spacs_focus)
        //                }
        //            }
        //        })


        binding.textViewPopMenu.setOnClickListener {
            //创建PopupWindow，用于承载气泡菜单
            val pop = PopupWindow(activity)
            pop.animationStyle = R.style.popoMenuAnim
            //设置窗口出现时获取焦点，这样在按下返回键时，窗口才会消失
            pop.isFocusable = true

            //向Fragment容器(FrameLayout)中加入一个View作为上层容器和遮罩
            val maskView = View(context)
            maskView.setBackgroundColor(Color.DKGRAY)
            maskView.alpha = 0.5f

            val rootView = view as FrameLayout
            rootView.addView(
                maskView,
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT
            )
            maskView.setOnClickListener {
                //隐藏弹出窗口
                pop.dismiss();
            }

            pop.setOnDismissListener {
                //去掉蒙板
                rootView.removeView(maskView)
            }
            //加载气泡图像，以作为window的背景
            val drawable = resources.getDrawable(R.drawable.pop_bk, null)
            //设置气泡图像为window的背景
            pop.setBackgroundDrawable(drawable)
            //加载菜单项资源，是用LinearLayout模拟的菜单
            val menuView = LayoutInflater.from(activity)
                .inflate(R.layout.pop_menu_layout, null) as LinearLayout
            //设置window中要显示的View
            pop.contentView = menuView
            //计算一下菜单layout的实际大小然后获取之
            menuView.measure(0, 0)
            //显示窗口
            pop.showAsDropDown(it, -pop.contentView.measuredWidth - 10, -10);
        }

        //响应它发出的事件
        binding.refreshLayout.setOnRefreshListener {
            //执行刷新数据的代码写在这里，不过一般都是耗时的操作或访问网络，所以需要
            //开启另外的线程。
            //... ...
            //刷新完成，隐藏UFO
            binding.refreshLayout.isRefreshing = false
        }
    }

    //创建并初始化联系人页面，返回这个页面
    private fun createContactsPage(): View {
        if (tree.size() == 0) {
            //向树中添加节点
            //创建组们，组是树的根节点，它们的父节点为null
            val group1 = ContactsPageListAdapter.GroupInfo("特别关心", 0)
            val group2 = ContactsPageListAdapter.GroupInfo("我的好友", 1)
            val group3 = ContactsPageListAdapter.GroupInfo("朋友", 0)
            val group4 = ContactsPageListAdapter.GroupInfo("家人", 0)
            val group5 = ContactsPageListAdapter.GroupInfo("同学", 0)

            //添加节点数据会创建节点并返回
            groupNode1 = tree.addNode(null, group1, R.layout.contacts_group_item)
            groupNode2 = tree.addNode(null, group2, R.layout.contacts_group_item)
            groupNode3 = tree.addNode(null, group3, R.layout.contacts_group_item)
            groupNode4 = tree.addNode(null, group4, R.layout.contacts_group_item)
            groupNode5 = tree.addNode(null, group5, R.layout.contacts_group_item)

//            //第二层，联系人信息
//            //头像
//            var bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.contacts_normal)
//            //联系人1
//            val contact1 = ContactsPageListAdapter.ContactInfo("", "王二", "[在线]我是王二")
//            //头像
//            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.contacts_normal)
//            //联系人2
//            val contact2 = ContactsPageListAdapter.ContactInfo("", "王三", "[离线]我没有状态")
//            //添加两个联系人
//            tree.addNode(groupNode2, contact1, R.layout.contacts_contact_item)
//            tree.addNode(groupNode2, contact2, R.layout.contacts_contact_item)
        }
        //创建联系人页面View
        val v = layoutInflater.inflate(R.layout.contacts_page_layout, null);
        //获取页面里的RecyclerView，为它创建Adapter
        val recyclerView: RecyclerView = v.findViewById(R.id.contactListView)
        recyclerView.layoutManager = LinearLayoutManager(context)
        contactsAdapter = ContactsPageListAdapter(tree)
        recyclerView.adapter = contactsAdapter

        //响应假搜索控件的点击事件，显示搜索页面
        val searchViewStub = v.findViewById<View>(R.id.searchViewStub)
        searchViewStub.setOnClickListener {
            val intent = Intent(context, SearchActivity::class.java)
            startActivity(intent)
        }

        return v;
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is FragmentListener) {
            fragmentListener = context
        }
    }

    override fun onDetach() {
        super.onDetach()
        fragmentListener = null
    }

    override fun onStart() {
        //创建一个定时器Observable
        Observable.interval(5, TimeUnit.SECONDS).flatMap {
                //向服务端发出获取联系人列表的请求
                val service = fragmentListener!!.getChatServcie()
                service.getContacts().map {
                    //转换服务端返回的数据，将真正的负载发给观察者
                    if (it.retCode == 0) {
                        it.data
                    } else {
                        throw RuntimeException(it.errMsg)
                    }
                }
            }.retry()
            .subscribeOn(Schedulers.computation())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<List<ContactsPageListAdapter.ContactInfo>?> {
                override fun onSubscribe(d: Disposable) {
                    observableDisposable = d
                }

                override fun onNext(contactInfos: List<ContactsPageListAdapter.ContactInfo>) {
                    //将联系人们保存到“我的好友”组
                    //但注意，需先清空现有好友
                    tree.clearDescendant(groupNode2);
                    for (info in contactInfos) {
                        val node2 = tree.addNode(groupNode2, info, R.layout.contacts_contact_item)
                        //没有子节点了，不显示展开、收起图标
                        node2.isShowExpandIcon = false;
                    }
                    //通知RecyclerView更新数据
                    contactsAdapter!!.notifyDataSetChanged();
                }

                override fun onError(e: Throwable) {
                    //提示错误信息
                    Snackbar.make(binding.contentLayout,
                        "大王祸事了：$e.localizedMessage",
                        Snackbar.LENGTH_LONG).show()
                }

                override fun onComplete() {
                }
            })

        super.onStart()
    }

    override fun onStop() {
        super.onStop()

        //停止RxJava定时器
        observableDisposable?.dispose()
        observableDisposable=null
    }

    //为ViewPager派生一个适配器类
    internal inner class ViewPageAdapter : PagerAdapter() {
        override fun getCount(): Int {
            return listViews.size
        }

        //返回每一页的标题，参数是页号，从0开始
        override fun getPageTitle(position: Int): CharSequence? {
            when (position) {
                0 -> return makeTabItemTitle("消息", R.drawable.message_normal)
                1 -> return makeTabItemTitle("联系人", R.drawable.contacts_normal)
                2 -> return makeTabItemTitle("动态", R.drawable.space_normal)
                else -> return null
            }
        }

        override fun isViewFromObject(view: View, obj: Any): Boolean {
            return view == obj
        }

        //实例化一个子View，container是子View容器，就是ViewPager，
        //position是当前的页数，从0开始计
        override fun instantiateItem(container: ViewGroup, position: Int): Any {
            val v = listViews[position]
            //必须加入容器中
            container.addView(v)
            return v!!
        }

        override fun destroyItem(container: ViewGroup, position: Int, obj: Any) {
            container.removeView(obj as View)
        }

        //为参数title中的字符串前面加上iconResId所引用图像
        private fun makeTabItemTitle(title: String, iconResId: Int): CharSequence {
            val image = resources.getDrawable(iconResId, null)
            image.setBounds(0, 0, 40, 40)
            //Replace blank spaces with image icon
            val sb = SpannableString(" \n$title")
            val imageSpan = ImageSpan(image, ImageSpan.ALIGN_BASELINE)
            sb.setSpan(imageSpan, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            return sb
        }
    }
}
